/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.torresquintero.oncologos.common.vista;

import java.lang.reflect.Method;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.table.DefaultTableModel;

/**
 *Metodo para generar un TableModel dada una lista de Objetos.
 * @author Camilo Andres
 */
public class OncologosTableModel<T> extends DefaultTableModel {
    
    /**
     * Lista que posee los datos con los que se generara el TableModel.
     */
    private List<T> datos;
    /**
     * Atributos de la clase con los que se quiere generar el tableModel, separados por coma
     */
    private String atributos;
    /**
     * Columnas con las que se nombrara el TableMOdel, separadas por coma.
     */
    private String columnas;
    
    /**
     * Constructor
     * @param datos 
     */
    public OncologosTableModel(List<T> datos) {
        this.datos = datos;
    }
    /**
     * Metodo para llenar el TableMOdel.
     */
    public void inicializar(){
      String[] atrs=atributos.split(",");
      
      setColumnIdentifiers(columnas.split(","));
        for (Object object : datos) {
            try {
                addRow(obtenerAtributos(object, atrs));
            } catch (Exception ex) {
                Logger.getLogger(OncologosTableModel.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
      
      
    }
    /**
     * 
     * @param datos
     * @param atributos
     * @param columnas 
     */
    public OncologosTableModel(List<T> datos, String atributos, String columnas) {
        this.datos = datos;
        this.atributos = atributos;
        this.columnas = columnas;
        inicializar();
    }
    
    
    
    
    
    
    /*METODOS UTILITARIOS------------------------------------------------------------------*/
    public Object[] obtenerAtributos(Object objeto,String... parametros) throws Exception {

        ArrayList lista=new ArrayList();
        for (String parametro : parametros) {
            Object valor=getValor(parametro, objeto);
            if(valor instanceof Date){
                valor=DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT).format(valor);
            }
           lista.add(valor);


        }
        return lista.toArray();

    }
    /**
     * Metodo para obtener el valor del atributo del objeto.
     * el atributo puede estar anidado dentro de otros objetos.
     * @param atributo noombre del atributo, de la forma nombre.nombre....
     * @param objeto objeto al cual se le quiere extraer el valor.
     * @return un objeto.
     * @throws Exception 
     */
    public Object getValor(String atributo,Object objeto) throws Exception {

        String attrs[] = atributo.split("\\.");
        

        Object res = null;
        for (String att : attrs) {

            res = obtenerAtributo(att, objeto);
            if (res == null) {
                break;
            } else {
                objeto = res;
            }

        }
        return res;
    }
    /**
     * Obtener el valor del atributo navegando por toda la jerarquia de clases.
     * @param parametro parametro
     * @param objeto objeto donde se busca.
     * @return
     * @throws Exception 
     */
    public Object obtenerAtributo(String parametro, Object objeto) throws Exception {

        String par = parametro.substring(0, 1).toUpperCase() + parametro.substring(1);
        String metodo = "get" + par;
        Method m = null;
        Class clase = objeto.getClass();
        boolean encontrado = false;
        while (encontrado == false) {

            if (clase == null) {
                return null;
            }

            try {
                m = clase.getDeclaredMethod(metodo, null);
                encontrado = true;
            } catch (Exception exc) {

                clase = clase.getSuperclass();
                encontrado = false;


            }

        }
        Object o = m.invoke(objeto, null);
        return o;
    }

    public String darFormato(String parametro) {

        String par = parametro.substring(0, 1).toUpperCase() + parametro.substring(1);
        return "get" + par;
    }

    
    
    
}
